fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 子图1:指数走势
axes[0, 0].plot(df_fixed['Date'], df_fixed['Close'], 'b-', linewidth=2)
axes[0, 0].set_title('指数收盘价走势', fontsize=12)
axes[0, 0].set_ylabel('点位', fontsize=10)
axes[0, 0].grid(True, alpha=0.3)
if error_excess_change.any():
axes[0, 0].scatter(
df_fixed[error_excess_change]['Date'],
df_fixed[error_excess_change]['Close'],
color='red', s=50, zorder=5, label='异常涨跌')
axes[0, 0].legend()
# 子图2:日收益率分布
returns = df_fixed['Daily_Change'].dropna()
axes[0, 1].hist(returns, bins=30, color='steelblue', edgecolor='black')
axes[0, 1].axvline(returns.mean(), color='red', linestyle='--',
label=f'均值: {returns.mean():.4f}')
axes[0, 1].axvline(returns.median(), color='green', linestyle='--',
label=f'中位数: {returns.median():.4f}')
axes[0, 1].set_title('日收益率分布', fontsize=12)
axes[0, 1].set_xlabel('收益率', fontsize=10)
axes[0, 1].legend(fontsize=9)
axes[0, 1].grid(True, alpha=0.3)
# 子图3:成交量
axes[1, 0].bar(range(len(df_fixed)), df_fixed['Volume'],
color='coral', edgecolor='black')
axes[1, 0].set_title('成交量', fontsize=12)
axes[1, 0].set_xlabel('交易序号', fontsize=10)
axes[1, 0].grid(True, alpha=0.3, axis='y')
# 子图4:日内振幅
df_fixed['Amplitude'] = (
(df_fixed['High'] - df_fixed['Low']) / df_fixed['Low'] * 100
)
axes[1, 1].plot(df_fixed['Date'], df_fixed['Amplitude'],
'g-', linewidth=1.5)
axes[1, 1].axhline(df_fixed['Amplitude'].mean(), color='red',
linestyle='--', label='平均振幅')
axes[1, 1].set_title('日内振幅(%)', fontsize=12)
axes[1, 1].set_ylabel('振幅(%)', fontsize=10)
axes[1, 1].legend(fontsize=9)
axes[1, 1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print('=== 数据质量指标 ===')
print(f'1. 完整性: 缺失值比例={df_fixed.isnull().sum().sum() / df_fixed.size:.2%}')
print(f'2. 一致性: 逻辑错误已修复')
print(f'3. 准确性: {len(errors)}类错误已处理')
print(f'4. 有效记录: {len(df_fixed)}/{len(df_index)} ({len(df_fixed)/len(df_index):.1%})')